﻿
using ServiceStack;
using ServiceStack.Redis;
using ServiceStack.Redis.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace DataCollectService
{
    public class Entity
    {
        public string Id { get; set; }
    }


    public abstract class RedisRepositoryBase<TEntity> : IRepository<TEntity> where TEntity : Entity
    {

        #region 公共方法
        public virtual  TEntity Insert(TEntity entity,DateTime expireTime)
        {
            return Store(entity, expireTime);
        }
        public virtual void Update(TEntity entity,DateTime expireTime)
        {
            using (var redisClient = RedisManager.GetClient())
            {
                redisClient.Set<TEntity>(UrnKey<TEntity>(entity), entity,expireTime);
            }
        }
        public virtual TEntity GetById(object Id)
        {
            using (var redisClient = RedisManager.GetClient())
            {
                var redisTypedClient = redisClient.As<TEntity>();
                return redisTypedClient.GetById(Id);
            }
        }

        public virtual IList<TEntity> GetList(Func<TEntity, bool> predicate)
        {
            using (var redisClient = RedisManager.GetClient())
            {
                var redisTypedClient = redisClient.As<TEntity>();
                
                return redisTypedClient.GetAll().Where(predicate).ToList();
            }

        }

        //public virtual bool Remove(Func<TEntity, bool> predicate)
        //{
        //    using (var redisClient = RedisManager.GetClient())
        //    {
        //        var redisTypedClient = redisClient.As<TEntity>();

        //        return redisTypedClient
        //    }
        //}



        #endregion

        #region 内部实现方法
        /// <summary>
        /// 重新实现生成Key的方法(原方法为内部类,无法调用)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        internal string UrnKey<TEntity>(TEntity entity)
        {
            using (var redisClient = RedisManager.GetClient())
            {
                var redisNativeClient = redisClient as RedisNativeClient;
                return entity.ToUrn();
            }
        }

        internal TEntity Store(TEntity entity, DateTime expireTime)
        {
            using (var redisClient = RedisManager.GetClient())
            {
                var redisTypedClient = redisClient.As<TEntity>();
                entity = redisTypedClient.Store(entity);
                redisTypedClient.ExpireEntryAt(UrnKey<TEntity>(entity), expireTime);
                redisTypedClient.ExpireAt(UrnKey<TEntity>(entity), expireTime);
                return entity;
            }
        }
        #endregion
    }
}
